%option stack
%option noyywrap
dig		[0-9]
num1    [-+]?{dig}+\.?([eE][-+]?{dig}+)?
num2    [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)?
number  {num1}|{num2}
identifier [_|a-z|A-Z][_|a-z|A-Z|1-9]*


%{  
	#define TOKEN_NUMBER 1
    #define TOKEN_DECLARATION_NAME 2
	#define TOKEN_TRIANGLE_START 6
    #define TOKEN_TRIANGLE_END 7
    #define TOKEN_BEGIN_POINT 8
    #define TOKEN_END_POINT 9
    #define TOKEN_ROTATE_X 10
    #define TOKEN_ROTATE_Y 11
    #define TOKEN_ROTATE_Z 12
    #define TOKEN_COLOR 13
    #define TOKEN_MESH_START 16
    #define TOKEN_MESH_END 17
    #define TOKEN_TEXTURE 18
    #define TOKEN_TRUE 23
	#define TOKEN_FALSE 24
    #define TOKEN_FIN 255
    #define TOKEN_ERROR 1024
    #define TOKEN_IRRELEVANT 0
    
    
	#include <stdio.h>
	#include <string.h>
%}


%s DECLARATION
%x TEXTURE
%x MESH
%s POINT
%s TRIANGLE
%s ROTATE
%%

[\n]				
[ \t]
[ \b]


[\#declare]

mesh                {
                        yy_push_state(MESH);
                        return(TOKEN_MESH_START);       
                    }

pigment\ \{         |
texture\ \{         { 
                        yy_push_state(TEXTURE);
                        return(TOKEN_IRRELEVANT);
                    }

{identifier}        {
                          return(TOKEN_DECLARATION_NAME);                     
                    }

<TEXTURE>
{
    [\n]				
    [ \t]
    [ \b]

    [\=]
    
    \{              {
                        yy_push_state(TEXTURE);
                        return(TOKEN_IRRELEVANT);
                    }

    \}              {
                        yy_pop_state();
                        return(TOKEN_IRRELEVANT);
                    }

    .               {
                        return(TOKEN_IRRELEVANT);
                    }     
}


<MESH>
{   
    [\{]
    [\n]				
    [ \t]
    [ \b]

    triangle\{		{ 
                        yy_push_state(TRIANGLE);
                        return(TOKEN_TRIANGLE_START);
                    }
 
    rotate          {
                        yy_push_state(ROTATE);
                        return(TOKEN_IRRELEVANT);
                    }
  
    texture         {
                        return(TOKEN_TEXTURE);
                        yy_push_state(TEXTURE);
                    }
             

    \}              {
                        yy_pop_state();
                        return(TOKEN_MESH_END);
                    }

    .               { 
                        return(TOKEN_IRRELEVANT);
                    }
}

<TRIANGLE>
{
    [\,]
    \<              {
                        yy_push_state(POINT);
                        return(TOKEN_BEGIN_POINT);
                    }

    \}              {
                        yy_pop_state();
                        return(TOKEN_TRIANGLE_END);
                    }

}

<POINT>
{
    [\,]
    \>              {
                        yy_pop_state();
                        return(TOKEN_END_POINT);
                    }
    
    {number}        return(TOKEN_NUMBER);
 
}                   

<ROTATE>
{   
    x\*             return(TOKEN_ROTATE_X);
    y\*             return(TOKEN_ROTATE_Y);
    z\*             return(TOKEN_ROTATE_Z);
    {number}        {
                        yy_pop_state();
                        return(TOKEN_NUMBER);
                    }
}


<<EOF>>				return TOKEN_FIN;

.				    return TOKEN_ERROR;

%%				

#include "structdef.h"

struct Token readNextToken(){
	struct Token resultado;
	resultado.token = yylex();
    if(resultado.token == TOKEN_NUMBER)
    {
        resultado.f = atof(yytext);
        resultado.mustFree = false;
    }
    else
    {
        resultado.text = strdup(yytext);
        resultado.mustFree = true;
    }
    return resultado;
};
